package com.dd.logistics.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.logistics.entity.OutboundOrder;
import com.dd.logistics.entity.Inventory;
import com.dd.logistics.entity.SupplierProduct;
import com.dd.logistics.mapper.OutboundOrderMapper;
import com.dd.logistics.mapper.SupplierProductMapper;
import com.dd.logistics.service.InventoryService;
import com.dd.logistics.service.OutboundOrderService;
import com.dd.logistics.utils.OrderNumberGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
public class OutboundOrderServiceImpl extends ServiceImpl<OutboundOrderMapper, OutboundOrder> implements OutboundOrderService {
    
    @Autowired
    private InventoryService inventoryService;
    
    @Autowired
    private SupplierProductMapper supplierProductMapper;
    
    @Override
    public List<OutboundOrder> getOutboundOrderList() {
        QueryWrapper<OutboundOrder> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        return this.list(wrapper);
    }
    
    @Override
    public Page<OutboundOrder> getOutboundOrderPage(Integer current, Integer size) {
        Page<OutboundOrder> page = new Page<>(current, size);
        QueryWrapper<OutboundOrder> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        return this.page(page, wrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createOutboundOrder(OutboundOrder outboundOrder) {
        log.info("开始创建出库单，客户ID={}，供应商ID={}，商品编码={}，数量={}", 
                outboundOrder.getCustomerId(), outboundOrder.getSupplierId(), 
                outboundOrder.getProductCode(), outboundOrder.getQuantity());
        
        // 验证数据
        if (outboundOrder.getCustomerId() == null) {
            throw new RuntimeException("客户ID不能为空");
        }
        if (outboundOrder.getSupplierId() == null) {
            throw new RuntimeException("供应商ID不能为空");
        }
        if (outboundOrder.getProductCode() == null || outboundOrder.getProductCode().trim().isEmpty()) {
            throw new RuntimeException("商品编码不能为空");
        }
        if (outboundOrder.getQuantity() == null || outboundOrder.getQuantity() <= 0) {
            throw new RuntimeException("出库数量必须大于0");
        }
        
        // 检查商品是否存在
        QueryWrapper<SupplierProduct> productWrapper = new QueryWrapper<>();
        productWrapper.eq("product_code", outboundOrder.getProductCode().trim())
                     .eq("supplier_id", outboundOrder.getSupplierId())
                     .eq("status", 1); // 只查询启用状态的商品
        SupplierProduct product = supplierProductMapper.selectOne(productWrapper);
        
        if (product == null) {
            throw new RuntimeException("商品不存在或已被禁用");
        }
        
        // 检查库存是否充足
        if (!inventoryService.checkStock(product.getId(), outboundOrder.getQuantity())) {
            throw new RuntimeException("库存不足");
        }
        
        // 设置默认值
        outboundOrder.setOrderNumber(OrderNumberGenerator.generateOutboundNumber());
        outboundOrder.setStatus(OutboundOrder.STATUS_PENDING);
        
        boolean success = this.save(outboundOrder);
        if (success) {
            log.info("创建出库单成功，出库单号：{}", outboundOrder.getOrderNumber());
        } else {
            log.error("创建出库单失败");
        }
        
        return success;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmPicking(String orderNumber) {
        log.info("开始确认拣货，出库单号：{}", orderNumber);
        
        // 获取出库单
        OutboundOrder order = this.getByOrderNumber(orderNumber);
        if (order == null) {
            throw new RuntimeException("出库单不存在");
        }
        
        // 检查状态
        if (order.getStatus() != OutboundOrder.STATUS_PENDING) {
            throw new RuntimeException("出库单状态不正确，当前状态：" + order.getStatusName());
        }
        
        // 更新状态为已拣货
        order.setStatus(OutboundOrder.STATUS_PICKED);
        boolean success = this.updateById(order);
        
        if (success) {
            log.info("确认拣货成功，出库单号：{}", orderNumber);
        } else {
            log.error("确认拣货失败，出库单号：{}", orderNumber);
        }
        
        return success;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmOutbound(String orderNumber) {
        log.info("开始确认出库，出库单号：{}", orderNumber);
        
        // 获取出库单
        OutboundOrder order = this.getByOrderNumber(orderNumber);
        if (order == null) {
            throw new RuntimeException("出库单不存在");
        }
        
        // 检查状态
        if (order.getStatus() != OutboundOrder.STATUS_PICKED) {
            throw new RuntimeException("出库单状态不正确，当前状态：" + order.getStatusName());
        }
        
        try {
            // 更新库存
            boolean success = inventoryService.updateQuantity(order.getProductCode(), -order.getQuantity());
            if (!success) {
                throw new RuntimeException("更新库存失败");
            }
            
            // 更新出库单状态
            order.setStatus(OutboundOrder.STATUS_COMPLETED);
            success = this.updateById(order);
            
            if (success) {
                log.info("确认出库成功，出库单号：{}", orderNumber);
            } else {
                log.error("确认出库失败，出库单号：{}", orderNumber);
                throw new RuntimeException("更新出库单状态失败");
            }
            
            return true;
        } catch (Exception e) {
            log.error("确认出库异常，出库单号：{}，原因：{}", orderNumber, e.getMessage());
            throw new RuntimeException("确认出库失败：" + e.getMessage());
        }
    }
    
    @Override
    public OutboundOrder getByOrderNumber(String orderNumber) {
        if (orderNumber == null || orderNumber.trim().isEmpty()) {
            return null;
        }
        QueryWrapper<OutboundOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("order_number", orderNumber.trim());
        return this.getOne(wrapper);
    }
} 